/******************************************************************************
 * @brief    tty串口打印驱动
 *
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs: 
 * Date           Author       Notes 

 ******************************************************************************/
#include "zb32l03x_hal.h"
#include "Ringbuff.h"
#include <stdio.h>
#include <string.h>
#include "bsp_usart.h"
#include "tty.h"

#if (TTY_RXBUF_SIZE & (TTY_RXBUF_SIZE - 1)) != 0 
    #error "TTY_RXBUF_SIZE must be power of 2!"
#endif

#if (TTY_TXBUF_SIZE & (TTY_TXBUF_SIZE - 1)) != 0 
    #error "TTY_RXBUF_SIZE must be power of 2!"
#endif


static unsigned char rxbuf[TTY_RXBUF_SIZE];         /*接收缓冲区 */
static unsigned char txbuf[TTY_TXBUF_SIZE];         /*发送缓冲区 */
static Ring_t rbsend, rbrecv;                   /*收发缓冲区管理*/

/*
 * @brief	    串口初始化
 * @param[in]   baudrate - 波特率
 * @return 	    none
 */
static void uart_init(int baudrate)
{
    RingBuff_Create(&rbsend, txbuf, sizeof(txbuf));/*初始化环形缓冲区 */
    RingBuff_Create(&rbrecv, rxbuf, sizeof(rxbuf)); 
    
    bsp_usart_init();

}

/*
 * @brief	    向串口发送缓冲区内写入数据并启动发送
 * @param[in]   buf       -  数据缓存
 * @param[in]   len       -  数据长度
 * @return 	    实际写入长度(如果此时缓冲区满,则返回len)
 */
static uint32_t uart_write(const void *buf, unsigned int len)
{   
    uint32_t ret;
    ERR_E err ;
    ret=RingBuff_Write(&rbsend, (uint8_t *)buf, len, &err);
    return ret; 
}

/*
 * @brief	    读取串口接收缓冲区的数据
 * @param[in]   buf       -  数据缓存
 * @param[in]   len       -  数据长度
 * @return 	    (实际读取长度)如果接收缓冲区的有效数据大于len则返回len否则返回缓冲
 *              区有效数据的长度
 */
static unsigned int uart_read(void *buf, unsigned int len)
{
    uint32_t ret;
    ERR_E err ;
    ret=RingBuff_Read(&rbrecv, (uint8_t *)buf, len, &err);
    return ret; 
}

/*发送缓冲区满*/
static bool tx_isfull(void)
{
    return RingBuff_GetLen(&rbsend) == TTY_TXBUF_SIZE;
}

/*接收缓冲区空*/
bool rx_isempty(void)
{
    return RingBuff_GetLen(&rbrecv) == 0;
}

/*控制台接口定义 -------------------------------------------------------------*/
const tty_t tty = {
    uart_init,
    uart_write,
    uart_read,
    tx_isfull,
    rx_isempty
};

void tty_process(void)
{
    uint8_t buff[128];
    ERR_E err;
    uint32_t len;
    len = RingBuff_Read(&rbsend, (uint8_t *)buff, sizeof(buff), &err);
    bsp_usart_sendbuff(buff, len);
    len = bsp_usart_read(buff);
    if (len)
    {
      RingBuff_Write(&rbrecv, (uint8_t *)buff, len, &err);
    }
}